#include "NodePort.h"
#include "vmLibrary.h"
#include "DiagramScene.h"
#include "AbstractShapeItem.h"
#include "LineItem.h"
#include "AbstractManager.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>


NodePort::NodePort(AbstractShapeItem* parent)
	:QAbstractGraphicsShapeItem(parent)
{
	this->setVisible(true);
	this->_parent = parent;
}

NodePort::~NodePort(void)
{
}

void NodePort::setPortInitVisible()
{
	if ( this->getClass() != CLASS_REQUIRED) {
		this->setVisible(false);
	}
}
void NodePort::setY( int y )
{
	this->_y = y;
}

void NodePort::setX( int x )
{
	this->_x = x;
}

int NodePort::x()
{
	return this->_x;
}

int NodePort::y()
{
	return this->_y;
}

const std::string & NodePort::getName() const {
	return this->_name;
}

void NodePort::setName( const std::string & name ) {
	this->_name = name;
}

void NodePort::mousePressEvent( QGraphicsSceneMouseEvent* event)
{	
	if ( event->button() == Qt::LeftButton ) {
		_line = new QGraphicsLineItem(QLineF(event->scenePos(),event->scenePos()));
		_line->setPen(QColor("#999999"));
		this->scene()->addItem(_line);
	} else {
		this->scene()->removeItem(_line);
		this->_line = NULL;
	}
}

void NodePort::mouseMoveEvent( QGraphicsSceneMouseEvent* event)
{
	if ( _line != NULL ) {
		AbstractManager* manager = this->_parent->getManager();
		NodePort* collidePort = manager->getCollidePort(event->scenePos());

		// 如果在拉線的時候有碰到合法可以連接的port則把線的一頭吸過去port的圓心
		if ( collidePort != NULL && collidePort != this && manager->verifyLink(collidePort, this)) {
			collidePort->setBrush(QBrush("#00FFFF"));
			collidePort->setPen(QPen(QBrush("#00FFFF"), 3));
			QPointF StickyPos(collidePort->mapToScene(collidePort->x() + NodePort::RADIUS, collidePort->y() + NodePort::RADIUS));
			QLineF newLine(_line->line().p1(), StickyPos.toPoint());
			_line->setLine(newLine);
		} else {
			QLineF newLine(_line->line().p1(), event->scenePos());
			_line->setLine(newLine);
		}
	}
}

int NodePort::getPortIOType()
{
	return this->_portIOType;
}

std::vector<LineItem*>& NodePort::getPortLineList()
{
	return this->_portLineList;
}

void NodePort::updateLinePosition()
{
	for ( int i = 0; i < _portLineList.size(); ++i )
	{
		_portLineList.at(i)-> updatePosition();
	}
}

void NodePort::removeAllLinks()
{
	for ( int i = _portLineList.size()-1; i >= 0 ; --i )
	{
		_portLineList.at(i)->removeFromScene();
	}
}

AbstractShapeItem* NodePort::getParent()
{
	return this->_parent;
}

QPainterPath NodePort::shape() const
{
	QPainterPath path;
	path.addEllipse(this->_x, this->_y, NodePort::RADIUS*2, NodePort::RADIUS*2);
	return path;
}

void NodePort::removeLineFromVector( LineItem* line )
{
	for ( auto itr = _portLineList.begin(); itr != _portLineList.end(); ++itr )
	{
		if ( *itr == line ) {
			_portLineList.erase(itr);
			this->update();
			return;
		}
	}
}

void NodePort::setPortIOType( int type )
{
	this->_portIOType = type;
}

bool NodePort::isConnected()
{
	if(_portLineList.size()==0)
		return false;
	return true;
}
